package net.metashare.grah.pogo

import net.metashare.grah.GraphObjectDecorator
import net.metashare.grah.Node

import net.metashare.grah.NodeHandler
import org.codehaus.groovy.runtime.MethodClosure

/**
 * Grah is a notion produced by metashare.net
 * User: dsherema
 * Date: May 5, 2010
 * Time: 1:02:55 PM
 *
 */
class PogoDecorator implements GraphObjectDecorator, NodeHandler {

  static def PogoDecorator instance = new PogoDecorator()
  def debug = true


  def Node createNode(Object o) {
    return new PogoNode(o)
  }





  def Node wrap(Object o) {
    println "Trying to wrap object $o as a Node:"

    if (o instanceof Node) {
      println "Warning: cannot cast a graphy Node as a Graphy Node!"
      return o
    }
    Node node = new PogoNode(o)
    def methods = [node.&edges, node.&neighbors, node.&connect, node.&connect, node.&direct ]
    o.metaClass.node = node
    methods.each() { MethodClosure method ->
      if (debug) println "adding method " + method.getMethod()
      //o.metaClass."$method.$getMethod()" = method
      o.metaClass.methods.add(method)
    }
    o.isWrapped={true}
    return node
  }


  def Object unwrap(Node n) {
    (n as PogoNode).object
  }


  def Node createEdge(Object tail, Object head, Object data) {
    return new PogoEdge( tail, head, data, false);  //To change body of implemented methods use File | Settings | File Templates.
  }
  def Node createEdge(Object tail, Object head, Object data, Boolean directed ) {
      return new PogoEdge( tail, head, data, directed);  //To change body of implemented methods use File | Settings | File Templates.
    }

  def NodeHandler getDefaultNodeHandler() {
    def handler = [
            "wrap": { (it instanceof PogoNode) ? it : new PogoNode(it) },
            "unwrap": { Node it -> return (it as PogoNode).object}
        ] as NodeHandler
    return handler
  }


}
